#ifndef VTKIMPORTFUNCTIONS_HPP
#define VTKIMPORTFUNCTIONS_HPP

#include "meshBase.hpp"
#include "solverBaseTypes_fwd.hpp"
#include "streamAccess.hpp"
#include "typeHelpers.hpp"
#include "tinyxml2.h"
#include "functionParserWrapper.hpp"

#include <filesystem>


namespace hms::vtk {

namespace xml = tinyxml2;

void readXML( xml::XMLDocument*, const fs::path& );

std::unique_ptr<xml::XMLDocument> readXML( const fs::path& );

void getBoundaryDoc(
	xml::XMLDocument* doc, const fs::path& caseDir,
	bool& dummyCreated, bool dryRun
);
void getConstantFieldsDoc(
	xml::XMLDocument* doc, const fs::path& caseDir,
	bool& dummyCreated, bool dryRun
);
void getSourceFieldsDoc(
	xml::XMLDocument* doc, const fs::path& caseDir,
	bool& dummyCreated, bool dryRun
);
void getBindingDoc(
	xml::XMLDocument* bindingFile,
	const fs::path& bindingFilePath
);
void getBindingDoc(
	xml::XMLDocument* bindingFile,
	const fs::path& caseDir, const std::string& caseName
);

/* dummy file wouldn't make sense */
std::unique_ptr<xml::XMLDocument> getBindingDoc(
	const fs::path& caseDir, const std::string& caseName
);

bool tryMeshExtensions( fs::path& meshPath );

template<typename Derived>
void textToMatrix(
	const xml::XMLElement* elem,
	const Eigen::DenseBase<Derived>& matrix
);

template<typename Derived, typename MeshType>
void textToFieldValues(
	const xml::XMLElement* elem,
	Eigen::DenseBase<Derived>& values,
	const MeshBase<MeshType>& mesh,
	Uniformity isUniform
);


std::vector<FunctionParserWrapper> readFunctions(
	const xml::XMLElement* parent,
	Index nComponents,
	bool optimise
);

FunctionParserWrapper readFunction(
	const xml::XMLElement* parent,
	Index component,
	bool optimise = false );

/* use this function for boundary patches */
TimeSeries readTimeSeries(
	const xml::XMLElement* parent,
	Index nComponents,
	Index nCols
);

/* use this function for source fields */
template<typename MeshType>
TimeSeries readTimeSeries(
	const xml::XMLElement* parent,
	Index nComponents,
	const MeshBase<MeshType>& mesh,
	Uniformity isUniform
);


const xml::XMLElement* lastWrittenElement( const xml::XMLDocument* doc );

scalar lastWrittenTime( const xml::XMLElement* );
scalar lastWrittenTime( const fs::path& caseDir, const std::string& caseName );

std::string lastWrittenFilename( const xml::XMLElement* );
fs::path lastWrittenFile( const xml::XMLElement*, const fs::path& caseDir );
fs::path lastWrittenFile( const fs::path& caseDir, const std::string& caseName );

std::pair<fs::path, scalar> lastWrittenFileAndTime(
	const fs::path& caseDir,
	const std::string& caseName
);

} // end namespace hms::vtk

#include "vtkFunctions_import.tpp"

#endif